package com.tanhua.dubbo.api.mongo;

import com.tanhua.domain.mongo.*;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.PublishVo;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 圈子服务接口实现类
 */
@Service
public class PublishApiImpl implements PublishApi{

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 发布动态
     */
    @Override
    public String savePublish(PublishVo publishVo) {
        Long userId = publishVo.getUserId();//当前发布动态的用户id

        long nowTime = System.currentTimeMillis();
        //1.将接收到数据 保存到 发布表(动态表)
        Publish publish = new Publish();
        BeanUtils.copyProperties(publishVo,publish); //用户id 文本内容 经纬度 图片url集合
        publish.setId(ObjectId.get());  //主键id 后续关联表中要使用此id
        publish.setPid(1l);//此值没有用到
        publish.setLocationName(publishVo.getLocation());//地址位置
        publish.setSeeType(1);//谁可以看 1-公开 2...
        publish.setCreated(nowTime);//动态发布时间
        mongoTemplate.insert(publish);
        //2.往相册表插入数据(跟发布表有关系-发布id)
        Album album = new Album();
        album.setId(ObjectId.get());
        album.setPublishId(publish.getId());//对应动态表主键id
        album.setCreated(nowTime);//创建时间
        mongoTemplate.insert(album,"quanzi_album_"+userId);
        //3.先根据登录用户id查询好友表，得到好友ids
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);
        if(!CollectionUtils.isEmpty(friendList)) {
            //4.根据好友的id动态拼接表名，往好友时间表插入数据(跟发布表有关系-发布id)
            for (Friend friend : friendList) {
                Long friendId = friend.getFriendId();

                TimeLine timeLine = new TimeLine();
                timeLine.setId(ObjectId.get());
                timeLine.setUserId(userId);//谁发布动态的用户id
                timeLine.setPublishId(publish.getId());//发布id 跟动态发布表主键有关系的
                timeLine.setCreated(nowTime);//发布时间
                mongoTemplate.insert(timeLine,"quanzi_time_line_"+friendId);
            }
        }

        return publish.getId().toHexString();
    }

    /**
     * 好友动态分页查询
     */
    @Override
    public PageResult<Publish> findPagePublishByFriend(Long userId, int page, int pagesize) {
        //1.根据当前用户id分页查询自己的好友时间线表
            //a.查询总记录数
        Query query = new Query();
        query.with(Sort.by(Sort.Direction.DESC,"created"));
        query.limit(pagesize).skip((page-1)*pagesize);
        long counts = mongoTemplate.count(query, TimeLine.class, "quanzi_time_line_" + userId);
            //b.查询当前页面需要显示的数据
        List<TimeLine> timeLineList = mongoTemplate.find(query, TimeLine.class, "quanzi_time_line_" + userId);
        //2.根据发布id查询发布表数据
        List<Publish> publishList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(timeLineList)){
            for (TimeLine timeLine : timeLineList) {
                ObjectId publishId = timeLine.getPublishId();//好友动态数据的发布id
                Publish publish = mongoTemplate.findById(publishId, Publish.class);
                if(publish == null){//实际系统中不会存在此问题
                    continue;
                }
                publishList.add(publish);//将动态数据放入集合中 返回PageResult
            }
            Long pages = counts/pagesize + (counts%pagesize > 0 ? 1:0);
            return new PageResult<>(counts,(long)pagesize,pages,(long)page,publishList);
        }
        //3.封装好友动态分页数据返回
        return null;
    }

    /**
     * 推荐动态分页查询（陌生人动态）
     */
    @Override
    public PageResult<Publish> findPagePublishByRecommend(Long userId, int page, int pagesize) {
        //1.根据当前用户id分页查询自己的好友时间线表
        //a.查询总记录数
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));//根据当前用户id 查询推荐的动态ids
        query.with(Sort.by(Sort.Direction.DESC,"created"));
        query.limit(pagesize).skip((page-1)*pagesize);
        long counts = mongoTemplate.count(query, RecommendQuanzi.class);
        //b.查询当前页面需要显示的数据
        //db.getCollection("recommend_quanzi").find({userId:1}).sort({"created":-1}).limit(10).skip(0)
        List<RecommendQuanzi> recommendQuanziList = mongoTemplate.find(query, RecommendQuanzi.class);
        //2.根据发布id查询发布表数据
        List<Publish> publishList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(recommendQuanziList)){
            for (RecommendQuanzi recommendQuanzi : recommendQuanziList) {
                ObjectId publishId = recommendQuanzi.getPublishId();//好友动态数据的发布id
                Publish publish = mongoTemplate.findById(publishId, Publish.class);
                if(publish == null){//实际系统中不会存在此问题
                    continue;
                }
                publishList.add(publish);//将动态数据放入集合中 返回PageResult
            }
            Long pages = counts/pagesize + (counts%pagesize > 0 ? 1:0);
            return new PageResult<>(counts,(long)pagesize,pages,(long)page,publishList);
        }
        //3.封装好友动态分页数据返回
        return null;
    }

    /**
     * 用户动态分页查询（我的动态）
     * @param userId
     * @param page
     * @param pagesize
     * @return
     */
    @Override
    public PageResult<Publish> findPagePublishByUserId(Long userId, int page, int pagesize) {
        //1.根据当前用户id分页查询自己的好友时间线表
        //a.查询总记录数
        Query query = new Query();
        query.with(Sort.by(Sort.Direction.DESC,"created"));
        query.limit(pagesize).skip((page-1)*pagesize);
        long counts = mongoTemplate.count(query, Album.class, "quanzi_album_" + userId);
        //b.查询当前页面需要显示的数据
        List<Album> albumList = mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);
        //2.根据发布id查询发布表数据
        List<Publish> publishList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(albumList)){
            for (Album album : albumList) {
                ObjectId publishId = album.getPublishId();//好友动态数据的发布id
                Publish publish = mongoTemplate.findById(publishId, Publish.class);
                if(publish == null){//实际系统中不会存在此问题
                    continue;
                }
                publishList.add(publish);//将动态数据放入集合中 返回PageResult
            }
            Long pages = counts/pagesize + (counts%pagesize > 0 ? 1:0);
            return new PageResult<>(counts,(long)pagesize,pages,(long)page,publishList);
        }
        //3.封装好友动态分页数据返回
        return null;
    }

    /**
     * 单条动态
     * publishId:动态发布id
     */
    @Override
    public Publish findPublishById(String publishId) {
        return mongoTemplate.findById(publishId,Publish.class);
    }

    /**
     * 根据动态发布id更新状态
     * @param message
     * @param state
     */
    @Override
    public void updateById(String message, Integer state) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(new ObjectId(message)));
        Update update=  new Update();
        update.set("state",state);
        mongoTemplate.updateFirst(query,update,Publish.class);
    }
}
